<?php
declare(strict_types=1);
namespace App\Service\Instance;
use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Model\User;
use App\Service\UserService;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Hyperf\Context\ApplicationContext;
use Hyperf\Utils\Traits\StaticInstance;
use mysql_xdevapi\CrudOperationSkippable;

/**
 * jwt生成类
 * Class JwtInstance
 * @package App\Service\Instance
 */
class JwtInstance extends Instance
{
    public const KEY = 'question';
    public const ALG = 'HS256';
    public const EXPIRE_TIME = 3600 * 24 * 30;
    public ?int $id = null;
    public ?array $user = null;

    /**
     * 获取用户id
     * @return int|null
     */
    public function getId() : ?int
    {
        return $this->id;
    }

    /**
     * 解析token
     * @param string $token
     * @return $this
     */
    public function decode(string $token) : self{
        try {
            $decode = (array) JWT::decode($token,new Key(self::KEY,self::ALG));
        }catch (ExpiredException $e){
            throw new BusinessException(ErrorCode::Token_EXPIRED);
        }catch (\Throwable $e){
            throw new BusinessException(ErrorCode::SERVER_ERROR,$e->getMessage());
        }
        if ($id = $decode['id']){
            $this->id = $id;
            $this->user = $this->getUser();
        }
        return $this;
    }

    /**
     * 生成jwt token
     * @param User $user
     * @return string
     */
    public function encode(User $user){
        $this->id = $user->id;
        return JWT::encode([
            'id' => $user->id,
            'exp' => time() + self::EXPIRE_TIME,
            ],self::KEY,self::ALG);
    }

    /**
     * 获取用户详情
     * @return array|null
     */
    public function getUser() :?array{
        if ($this->user == null){
            if (!empty($id = $this->getId())){
//                if ($user = User::findFromCache($id)){//等同于Cache set 和 Cache get
//                    $this->user = $user->toArray();
//                }
                $this->user = ApplicationContext::getContainer()->get(UserService::class)->getUserInfoFromCache($id);
            }
        }
//        $instance = new User();
//        $data = Cache::get($key);
//        if (is_null($data)) {
//            $model = $instance->newQuery()->where($primaryKey, '=', $id)->first();
//            Cache::set($key, [], $ttl);
//        }
        return $this->user;
    }

}